package cn.laixueit.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.laixueit.annotation.GlobalLog;
import cn.laixueit.base.R;
import cn.laixueit.utils.CodeUtils;
import cn.laixueit.vo.ResultPage;
import cn.laixueit.vo.SoftVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.laixueit.pojo.Soft;
import cn.laixueit.service.SoftService;
import cn.laixueit.mapper.SoftMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.LongStream;

/**
 *
 */
@Service
public class SoftServiceImpl extends ServiceImpl<SoftMapper, Soft>
        implements SoftService {

    @Resource
    private SoftMapper softMapper;

    @Resource
    private CodeUtils codeUtils;

    @Override
    public R listPage(Page<Soft> pageInfo, SoftVo softvo) {
        QueryWrapper<Soft> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .like(StringUtils.isNotBlank(softvo.getName()), Soft::getName, softvo.getName())
                .eq(ObjectUtil.isNotEmpty(softvo.getIsCrack()), Soft::getIsCrack, softvo.getIsCrack())
                .eq(ObjectUtil.isNotEmpty(softvo.getType()), Soft::getType, softvo.getType())
                .eq(ObjectUtil.isNotEmpty(softvo.getIsShow()), Soft::getIsShow, softvo.getIsShow())
                .eq(ObjectUtil.isNotEmpty(softvo.getIsDelete()), Soft::getIsDelete, softvo.getIsDelete())
                .and(ObjectUtil.isNotEmpty(softvo.getIsPay()), // 如果查询免费的也需要查询价格为0 或者折扣0折的
                        qr->qr.eq(Soft::getIsPay, softvo.getIsPay())
                                .or().eq(Soft::getMoney,0)
                                .or().eq(Soft::getDiscount,0)
                );
        if(ObjectUtil.isNotEmpty(softvo.getOrderHot()) && softvo.getOrderHot()){
            wrapper.lambda().orderByDesc(Soft::getIsHot ,Soft::getCreateTime);
        }else{
            wrapper.lambda().orderByAsc(Soft::getCreateTime);
        }
        Page<Soft> softPage = page(pageInfo, wrapper);
        ArrayList<SoftVo> softVos = new ArrayList<>();
        List<Soft> records = softPage.getRecords();
        records.forEach(x -> {
            SoftVo vo = calculateNewPrice(x);
            softVos.add(vo);
        });

        return R.ok().put("total", softPage.getTotal()).put("rows", softVos);
    }

    @Override
    public void saveOrUpdateSoft(Soft soft) {
        if (StringUtils.isBlank(soft.getCode())) {
            String code = codeUtils.getNewCode();
            soft.setCode(code);
        }
        saveOrUpdate(soft);
    }

    /**
     * 首页显示，需要返回分页页码
     *
     * @param pageInfo
     * @param softvo
     * @return
     */
    @Override
    public R softpage(Page<Soft> pageInfo, SoftVo softvo) {
        R r = this.listPage(pageInfo, softvo);
        long pages = pageInfo.getPages();//总页数
        long current = pageInfo.getCurrent();//当前页
        long size = pageInfo.getSize();//每页显示数量
        ResultPage resultPage = this.calculatePageNo(pages, current, size, 5);
        return r.put("resultPage",resultPage);
    }

    @Override
    @GlobalLog("查询软件详情及随机查询6个软件")
    public R softdetail(String id) {
        Soft soft = getById(id);
        SoftVo softVo = calculateNewPrice(soft);
        List<Soft> randSoftList = softMapper.selectList(lambdaQuery()
                .select(Soft::getId,Soft::getName,Soft::getIsPay,Soft::getIsCrack)
                .last("order by rand() limit 6")
                .getWrapper());
        return R.ok().put("obj",softVo).put("randSoftList",randSoftList);
    }

    /**
     * 计算页码分页器
     * @param pages 总页数
     * @param current 当前页
     * @param size 每页显示数量
     * @param restrictNum 页码数量
     * @return 分页条
     */
    private ResultPage calculatePageNo(long pages, long current, long size, Integer restrictNum) {
        LinkedList<Long> longs = new LinkedList<>();
        // 算出当前显示是否需要计算
        // 第一页，直接显示1-总页数
        long start = 1;
        long end = restrictNum+1;
        Double ceil = Math.ceil(Double.valueOf(restrictNum)/2);
        int i = ceil.intValue();//中间数
        Long min = Math.min(pages, restrictNum);
        if (current <= i || pages <= restrictNum) { //当前页<=中间数或者总页数<=页码数
            end = min;
        }else if(current == pages){ // 最后一页
            // 当前页 = 总页数
            // 总页数是否大于限定页数
            if(pages>restrictNum){ // 10 > 5 ,10
                start = pages - restrictNum + 1;// 10-5+1 = 6
                end = pages; // 10
            }else{ // 4 < 5 ,5
                start = 1;
                end = pages;
            }
        }else{ // 4 , 10, 5
            start = current - i + 1;
            end = start + restrictNum - 1;
            if(end > pages){
                start = pages - restrictNum +1;
                end = start + restrictNum - 1;
            }
        }
        LongStream.range(start, end+1).forEach(longs::add);
        Long[] array = longs.toArray(new Long[min.intValue()]);
        return  new ResultPage(current,size,pages,restrictNum,array);
    }

    /**
     * 计算成品的最终价格
     * @return
     */
    private SoftVo calculateNewPrice(Soft soft){
        SoftVo vo = new SoftVo();
        BeanUtil.copyProperties(soft,vo);
        BigDecimal discount = vo.getDiscount();
        if (ObjectUtil.isNotEmpty(discount)) {
            BigDecimal money = vo.getMoney();
            BigDecimal multiply = money.multiply(discount.divide(BigDecimal.valueOf(10)));
            vo.setNewPrice(multiply.setScale(2, BigDecimal.ROUND_UP));
        } else {
            vo.setDiscount(BigDecimal.TEN);
            vo.setNewPrice(vo.getMoney());
        }

        Boolean isPay = vo.getIsPay();
        if (isPay) {
            vo.setNewPrice(BigDecimal.ZERO);
        }
        return vo;
    }
}




